package com.info.zhiduoduo.admin.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.mapper.Condition;
import com.info.zhiduoduo.admin.model.formbean.project.ImportZddProjectTemplateFormBean;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.company.CompanyAccountFlowBizType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.listener.BaseAnalysisEventListener;
import com.info.zhiduoduo.core.service.CoreBrokerageService;
import com.info.zhiduoduo.core.service.CoreCompanyService;
import com.info.zhiduoduo.core.service.CoreInvoiceService;
import com.info.zhiduoduo.repository.entity.company.*;
import com.info.zhiduoduo.repository.entity.invoice.Invoice;
import com.info.zhiduoduo.repository.entity.maker.MakerAccount;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.entity.system.SystemProjectcategory;
import com.info.zhiduoduo.repository.mapper.company.CompanyMapper;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 导入历史成交的 项目
 *
 * @author tianyonghong
 * @create 2022/7/27
 */
@Getter
@Slf4j
public class UploadDealProjectListener extends BaseAnalysisEventListener<ImportZddProjectTemplateFormBean> {

    //解析后的数据集合
    List<ImportZddProjectTemplateFormBean> list = new ArrayList<>();

    //解析后的企业集合 key:companyName
    Map<String, Company> companyMap = new HashMap<>();

    //操作人员ID
    int operateUserId;
    //支付方式ID
    int payId;
    //是否计佣
    int whetherJiYong;
    CompanyMapper companyMapper;
    CoreCompanyService coreCompanyService;
    CoreInvoiceService coreInvoiceService;
    CoreBrokerageService coreBrokerageService;

    public UploadDealProjectListener(int operateUserId, int payId, int whetherJiYong, CompanyMapper companyMapper, CoreCompanyService coreCompanyService,
                                     CoreInvoiceService coreInvoiceService, CoreBrokerageService coreBrokerageService) {
        this.operateUserId = operateUserId;
        this.payId = payId;
        this.whetherJiYong = whetherJiYong;
        this.companyMapper = companyMapper;
        this.coreCompanyService = coreCompanyService;
        this.coreInvoiceService = coreInvoiceService;
        this.coreBrokerageService = coreBrokerageService;
    }

    @Override
    public void invoke(ImportZddProjectTemplateFormBean formBean, AnalysisContext analysisContext) {
        super.invoke(formBean, analysisContext);

        // 单条数据校验
        boolean result = checkValidExcelData(formBean, index);
        if (result) {
            list.add(formBean);
        }
    }

    /**
     * 数据校验
     *
     * @param formBean
     * @param index
     * @return
     */
    private boolean checkValidExcelData(ImportZddProjectTemplateFormBean formBean, int index) {
        // 验证企业是否都存在
        Company company = companyMap.get(formBean.getCompanyName());
        if (company == null) {
            company = companyMapper.getByCompname(formBean.getCompanyName());
            if (company == null) {
                errorPrompt.add("请检查第[" + index + "]行数据：企业未找到");
                return false;
            }
            companyMap.put(formBean.getCompanyName(), company);
        }

        // 记录企业默认支付数据
        CompanyParty companyParty = coreCompanyService.getCompanyDefaultPartyZdd(company.getCompid());
        if(companyParty == null){
            errorPrompt.add("请检查第[" + index + "]行数据：企业未配置默认业务支付方式");
            return false;
        }
        formBean.setPartyId(companyParty.getPartyId());

        //验证创客是否存在
        MakerAccount account = new MakerAccount().selectOne(Condition.create().like("idno", formBean.getIdno()));
        if (account == null) {
            errorPrompt.add("请检查第[" + index + "]行数据：创客未找到");
            return false;
        }else if(!account.getRealname().equals(formBean.getName())){
            errorPrompt.add("请检查第[" + index + "]行数据：创客名称不匹配");
            return false;
        }
        MakerStudio studio = new MakerStudio().selectById(account.getUserid());
        if (studio == null) {
            errorPrompt.add("请检查第[" + index + "]行数据：创客工作室未找到");
            return false;
        }
        //项目分类
        if (StringUtil.isNotEmpty(formBean.getCategory())) {
            if ("商业服务".equals(formBean.getCategory())) {
                formBean.setCategory("项目服务");
            } else if ("资本服务".equals(formBean.getCategory())) {
                formBean.setCategory("营销测试");
            } else if ("室内装饰及装修服务".equals(formBean.getCategory())) {
                formBean.setCategory("其他");
            }
            SystemProjectcategory category = new SystemProjectcategory().selectOne(Condition.create().eq("projectcategory", formBean.getCategory()));
            if (null != category) {
                formBean.setCategoryId(category.getProjectcategoryid());
            }
        }
        formBean.setCompid(company.getCompid());
        formBean.setPartyId(companyParty.getPartyId());
        formBean.setUserId(account.getUserid());
        formBean.setRealname(account.getRealname());
        formBean.setUsername(studio.getUsername());
        return true;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 有失败的数据，则返回
        if (CollectionUtils.isNotEmpty(errorPrompt)) {
            smartResult = SmartResult.fail(StatusMsg.StatusMsg_1109, errorPrompt);
            return;
        }
        // 新增项目数据
        if (CollectionUtils.isNotEmpty(list)) {
            // 校验企业导入金额
            SmartResult balanceResult = checkCompanyBalance();
            if(balanceResult.isFailed()){
                smartResult = balanceResult;
                return;
            }

            createData();
        }
        smartResult = SmartResult.success();
    }

    public SmartResult checkCompanyBalance() {
        // 按企业名分组
        Map<String, List<ImportZddProjectTemplateFormBean>> map = list.stream().collect(Collectors.groupingBy(ImportZddProjectTemplateFormBean::getCompanyName));
        for (Map.Entry<String, List<ImportZddProjectTemplateFormBean>> entry : map.entrySet()) {
            Company company = companyMap.get(entry.getKey());
            // 获取企业余额
            CompanyPayment companyPayment = coreCompanyService.getCompanyPayment(company.getCompid(), this.payId);
            if (companyPayment == null) {
                return SmartResult.fail(StatusMsg.StatusMsg_330);
            }
            double projectTotalAmount = list.stream().map(ImportZddProjectTemplateFormBean::getProjectAmount).reduce(Double::sum).orElse(0d);
            // 检查企业余额是否足够
            if (companyPayment.getBalance().compareTo(BigDecimal.valueOf(projectTotalAmount)) < 0) {
                //余额不足,返回报错
                return SmartResult.fail(StatusMsg.StatusMsg_365);
            }
        }
        return SmartResult.success();
    }

    public void createData() {
        for (ImportZddProjectTemplateFormBean bean : list) {
            // 获取企业余额
            CompanyPayment companyPayment = coreCompanyService.getCompanyPayment(bean.getCompid(), this.payId);
            if(companyPayment == null){
                throw new SmartException(StatusMsg.StatusMsg_330);
            }
            // 创建项目
            CompanyProject project = bean.toEntity(bean);
            project.setPayId(this.payId).setOfflinePayAdminid(operateUserId).setSupplementPersonnel(operateUserId);

            if (project.insert()) {
                /** 企业余额扣款 生成企业流水 start */
                BigDecimal beforeBalance = companyPayment.getBalance();
                BigDecimal currBalance = companyPayment.getBalance().subtract(project.getProjectdealamount());
                //企业余额修改
                companyPayment.setBalance(currBalance).updateById();
                CompanyAccountflow accountflow = new CompanyAccountflow().setCompid(project.getCompid())
                                                                         .setFlowname(project.getProjectname() + "项目付款给创客" + bean.getUsername())
                                                                         .setFlowtype(2)
                                                                         .setBizid(project.getProjectid())
                                                                         .setBizType(CompanyAccountFlowBizType.ZDD_PROJECT)
                                                                         .setPayId(project.getPayId())
                                                                         .setFlowAmount(project.getProjectdealamount())
                                                                         .setBeforeBalance(beforeBalance)
                                                                         .setCurrBalance(currBalance)
                                                                         .setBeforeFrozenBalance(companyPayment.getFrozenBalance())
                                                                         .setCurrFrozenBalance(companyPayment.getFrozenBalance())
                                                                         .setPayId(this.payId);
                accountflow.insert();
                /** 企业余额扣款 生成企业流水 end */

                // 补录发票
                Date now = new Date();
                Invoice invoice = coreInvoiceService.createZhiduoduoProjectInvoice(project.getProjectid());
                invoice.setState(Constants.invoicestate_4)
                       .setInvoicetype(project.getInvoicetype())
                       .setContent(project.getInvoicecontent())
                       .setApplyTime(now)
                       .setAccepttime(now)
                       .setFinishtime(project.getProjectfinish())
                       .setSupplementPersonnel(operateUserId)
                       .setSupplementTime(now)
                       .setWhetherSupplement(Constants.TRUE);
                invoice.updateById();
                if (0 != whetherJiYong) {
                    coreBrokerageService.prepareProjectBrokerage(bean.getCompid(), project.getUserid(), project.getProjectid(), ProjectType.ZHIDUODUO);
                    coreBrokerageService.handleZhiduoduoProjectPartnerBrokerage(project, 0, "");
                }
            }
        }
    }

}
